package com.heihu577.controller;

import com.heihu577.bean.AliyunOSSBean;
import com.heihu577.bean.MarkdownFile;
import com.heihu577.bean.enums.FxmlResources;
import com.heihu577.bean.enums.NamingsConfig;
import com.heihu577.controller.child.AliyunOSSController;
import com.heihu577.controller.child.MarkdownResultController;
import com.heihu577.util.FileUtils;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.fxml.FXML;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.stage.Window;

import java.io.File;
import java.io.IOException;

public class MyAppController {
    File checkedDirectory; // 当前选择的文件夹

    @FXML
    private TextField checkedInput; // 文件夹已选中提示
    @FXML
    private MenuItem openFile; // 打开文件夹
    @FXML
    private TextArea logs; // 日志输出框

    @FXML
    public CheckBox isConfigOSS; // 是否配置了 OSS

    @FXML
    public CheckBox isSelectedMarkdown; // 是否选择了 MD 文件夹

    @FXML
    private Button handleMd; // 开始处理 MD 文件按钮

    @FXML
        // 单机 阿里云 OSS 设置按钮
    void AliyunOSSAction(ActionEvent event) throws IOException {
        Stage stage = new Stage();
        FXMLLoader fxmlLoader = new FXMLLoader(FxmlResources.ALIYUN_OSS.getUrl()); // 通过 new FXMLLoader 的方式, 可以传递作用域
        Scene scene = new Scene(fxmlLoader.load());
        AliyunOSSController aliyunOSSController = (AliyunOSSController) fxmlLoader.getController();
        aliyunOSSController.setMyAppController(this); // 通过作用域传递过去当前 Controller
        stage.setTitle(NamingsConfig.OSS_TITLE.name);
        stage.setScene(scene);
        stage.show();
    }


    @FXML
        // 拖拽 MD 文件夹功能
    void checkedInputOnDragDropped(DragEvent event) {
        event.acceptTransferModes(TransferMode.ANY);
    }

    @FXML
        // 拖拽 MD 文件夹功能
    void checkedInputOnDragOver(DragEvent event) {
        Dragboard dragboard = event.getDragboard(); // 获取托盘
        if (dragboard.hasFiles()) {
            File file = dragboard.getFiles().get(0);
            if (file.isDirectory()) {
                // 用户已选择文件夹
                checkedDirectory = file;
                checkedInput.setText(file.getAbsolutePath());
                isSelectedMarkdown.setSelected(true);
            } else {
                // 用户未选择文件夹
                checkedInput.setText("请选择文件");
                isSelectedMarkdown.setSelected(false);
            }
        }
    }


    @FXML
        // 处理 MD 文件核心逻辑， 单机按钮后的事件
    void handleMdAction(ActionEvent event) {
        if (!isSelectedMarkdown.isSelected()) {
            // 没有选择任何内容
            printToLog("[-] 请选择MD文件夹,可以通过拖拽或导入的方式导入本地MD文件夹!");
            return;
        }
        if (!isConfigOSS.isSelected()) {
            // OSS 还没有连接上
            printToLog("[-] 请连接好 OSS 再使用本工具!");
            return;
        }
        File nowMd = FileUtils.findFileByLike(checkedDirectory, ".md");
        if (nowMd == null) {
            printToLog("[-] 当前目录下没有 MD 文件!");
            return;
        }
        printToLog("[+] 正在处理 " + nowMd.getAbsolutePath() + " 文件, 请稍等弹窗...");
        // 创建进度条
        ProgressBar progressBar = new ProgressBar(0);
        // 通过一个普通标签, 找 parent 的方法, 得到场景
        Scene scene = handleMd.getParent().getScene();
        // 得到整个窗口, 用来设置高度等信息
        Stage window = (Stage) scene.getWindow();
        // 增加高度, 准备给进度条腾出位置
        window.setHeight(window.getHeight() + 16);
        // 设置进度条的位置是无效的, 因为 VBox 不允许设置 setLayoutY, 无效, 会追加到程序底部, 那就设置成最宽的就行
        progressBar.setPrefWidth(window.getWidth());
        progressBar.setPrefHeight(15);
        // 得到根节点, 准备在里面加控件, 这里强制转换为 VBox 是因为当前 MyApp.fxml 中定义了当前页面是 VBox 类型, 否则不能强制转换
        VBox root = (VBox) scene.getRoot();
        // 将当前的进度条加入进去
        root.getChildren().addAll(progressBar);

        MarkdownFile markdownFile = FileUtils.parseMdImages(nowMd); // 根据当前选择的 MD, 生成 markdownFile 对象
        AliyunOSSBean aliyunOSSBean = new AliyunOSSBean();
        // 处理并弹窗
        aliyunOSSBean.uploadByMarkdownFile2(markdownFile, this, root, progressBar, window);
        /*
        老版本代码, 存在阻塞问题, 故抛弃...
        // 处理 MD, 并生成 MarkdownFile 对象
        // 准备上传到 AliyunOSS 中, 为了能够打印日志, 传入本对象
        AliyunOSSBean aliyunOSSBean = new AliyunOSSBean();
        aliyunOSSBean.uploadByMarkdownFile(markdownFile, this);
        // 最终结果, 可以打开一个新窗口, 在里面进行复制, 粘贴操作. 顺便打开 https://markdown.com.cn/editor/ 官网
        new Thread(() -> {
            // 每次单机按钮都产生新的线程对象, 可以处理很多不同的任务
            try {
                aliyunOSSBean.nowThread.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            Platform.runLater(() -> {
                // 操作 UI 之前使用 Platform.runLater 避免报错
                try {
                    Stage stage = new Stage();
                    FXMLLoader fxmlLoader = new FXMLLoader(FxmlResources.MARKDOWN_RESULT.getUrl()); // 通过 new FXMLLoader 的方式, 可以传递作用域
                    Scene scene = new Scene(fxmlLoader.load());
                    MarkdownResultController markdownResultController = (MarkdownResultController) fxmlLoader.getController();
                    markdownResultController.setMyAppController(this);
                    stage.setTitle(NamingsConfig.MARKDOWN_RESULT_TITLE.name + "[" + nowMd.getAbsolutePath() + "]");
                    stage.setScene(scene);
                    stage.setOnShown(e -> {
                        // 设置加载完毕的事件, 将处理结果放进去
                        markdownResultController.markdownContent.setText(aliyunOSSBean.resultMd.toString());
                        markdownResultController.setHostServices(markdownResultController.getHostServices());
                    });
                    stage.show();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        }).start();
        */
    }

    @FXML
        // 《选择 MD 文档位置》 按钮功能
    void openFileAction(ActionEvent event) {
//        FileChooser fileChooser = new FileChooser(); // 选择文件使用 FileChooser
//        fileChooser.setTitle("选择文件"); // 设置文件选择器名称
//        Window window = ((MenuItem) event.getSource()).getParentPopup().getOwnerWindow(); // 通过本次
//        File file = fileChooser.showOpenDialog(window); // 打开窗口, 并返回 File 对象
//        System.out.println(file);

        DirectoryChooser directoryChooser = new DirectoryChooser(); // 选择文件夹使用 DirectoryChooser
        directoryChooser.setTitle("请选择本地 MD 文件夹"); // 设置选择文件夹名称
        Window window = ((MenuItem) event.getSource()).getParentPopup().getOwnerWindow();
        checkedDirectory = directoryChooser.showDialog(window); // 选择文件, 并设置 File 类型的对象
        if (checkedDirectory != null && checkedDirectory.isDirectory()) {
            // 用户已选择文件
            checkedInput.setText(checkedDirectory.getAbsolutePath());
            isSelectedMarkdown.setSelected(true);
        } else {
            // 用户未选择文件
            checkedInput.setText("请选择文件");
            isSelectedMarkdown.setSelected(false);
        }
    }

    // 输出日志
    public void printToLog(String msg) {
        logs.setText(logs.getText() + "=========================\r\n" + msg + "\r\n");
        logs.positionCaret(logs.getLength()); // 每次设置到最后一行的操作
        logs.requestFocus();
    }

    // 更新 OSS 多选框的状态
    public void updateStatus() {
        AliyunOSSBean.initBean(); // 初始化 AliyunOSS, 并设置当前 config 状态
        if (AliyunOSSBean.checkStatus()) {
            // 判断是否配置了 AliyunOSSBean, 并且是否能够成功连接上
            isConfigOSS.setSelected(true);
            printToLog("[+] OSS 链接成功!");
        } else {
            isConfigOSS.setSelected(false);
            printToLog("[-] OSS 链接失败!");
        }
    }

    public void initialize() {
        updateStatus();
    }
}
